struct arcNode {
	int adjvex;
	int capacity;
	int reverse;
	arcNode(int next, int cap, int rev): adjvex(next), capacity(cap), reverse(rev) {}
};

int maxFlow_EK(vector< vector<int> > &map, int start, int end) {
	vector< vector<arcNode> > adjtable(map.size());
	mapToAdjtable(map, adjtable);
	int maxflow = 0;
	while(1) {
		vector<bool> visited(map.size(), false);
		int increment = dfs_EK(adjtable, start, end, visited, MAX_INT);
		if (increment)
			maxflow += increment;
		else
			break;
	}
	return maxflow;
}
int dfs_EK(vector< vector<arcNode> > &adjtable, int start, int end, vector<bool> &visited, int curflow) {
	visited[start] = true;
	if (start == end)
		return curflow;
	for (int i = 0; i != adjtable[start].size(); ++i) {
		int next = adjtable[start][i].adjvex;
		if (!visited[next] && adjtable[start][i].capacity) {
			int increment = dfs_EK(adjtable, next, end, visited, min(curflow, adjtable[start][i].capacity));
			if (increment) {
				int rev = adjtable[start][i].reverse;
				adjtable[start][i].capacity -= increment;
				adjtable[next][rev].capacity += increment;
				return increment;
			}
		}
	}
	return 0;
}
void mapToAdjtable(vector< vector<int> > &map, vector< vector<arcNode> > &adjtable) {
	for (int v = 0; v != map.size(); ++v) {
		for (int w = 0; w != map.size(); ++w) {
			if (map[v][w]) {
				adjtable[v].push_back(arcNode(w, map[v][w], adjtable[w].size()));
				adjtable[w].push_back(arcNode(v, 0, adjtable[v].size() - 1));
			}
		}
	}
}
inline int min(int ix, int iy) {
	return ix < iy ? ix : iy;
}